import json
import random

from django.contrib.auth import authenticate
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.views import View

import logging
import re

from django_redis import get_redis_connection

from celery_tasks.sms.tasks import send_sms_code_func
from ten_time_mall.libs.qiniuyun.qiniu_storage import storage
from ten_time_mall.libs.yuntongxun.ccp_sms import CCP
from ten_time_mall.settings.dev import qiniuyun
from ten_time_mall.utils.fastdfs.storage import FDFSStorage
from users.models import User

logger = logging.getLogger('django')

# Get sms_codes/(?P<mobile>1[3-9]\d{9})
"""发送短信验证码"""
class MobileMessageView(View):
    def get(self, request,mobile):
        """注册功能接口"""

        # 7. 生成短信验证码：生成6位数验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 8. 保存短信验证码
        # 短信验证码有效期，单位：300秒
        redis_conn = get_redis_connection('verify_code')
        redis_conn.setex('sms_%s' % mobile, 300, sms_code)

        # 9. 发送短信验证码
        # 不启用芹菜, 短信模板
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)

        # 启用芹菜,发送短信
        # send_sms_code_func(mobile, sms_code)

        # 10. 响应结果
        return JsonResponse({"success": True,
                             "message": "OK",
                             "sms_code": sms_code

                  })

# /users/
"""接收用户信息,实现注册功能,模型类中的username,和mobile默认自带唯一性unique的验证
"""

# Post 用户hahahha,的密码是123456abc
class RegisterView(View):
    def post(self,request):
        dict =json.loads(request.body.decode())
        username = dict['username']
        mobile = dict['mobile']
        sms_code = dict['sms_code']
        password = dict['password']

         # 2.校验(整体)
        if not all([username, password,mobile,sms_code]):
            return JsonResponse({'code':400,
                                 'errmsg':'缺少必传参数'})

        # 3.username检验
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return JsonResponse({'code': 400,
                                 'errmsg': 'username格式有误'})

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'code': 400,
                                 'errmsg': 'password格式有误'})
        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400,
                                 'errmsg': 'mobile格式有误'})

        # 1.查询mobile在mysql中的个数
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': '查询数据库出错'})


        # 8.sms_code检验 (链接redis数据库)
        redis_conn = get_redis_connection('verify_code')

        # 9.从redis中取值
        sms_code_server = redis_conn.get('sms_%s' % mobile)

        # 10.判断该值是否存在
        if not sms_code_server:
            return JsonResponse({'code': 400,
                                 'errmsg': '短信验证码过期'})

        # 11.把redis中取得值和前端发的值对比
        if sms_code != int(sms_code_server.decode()):
            return JsonResponse({'code': 400,
                                 'errmsg': '验证码有误'})

        try:
            user = User.objects.create_user(username=username,   # 自动实现密码的加密
                                        password=password,
                                        mobile=mobile)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': '保存到数据库出错,可能是由于用户名或手机号已经注册过'})

        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token =token
        user.save()


        return JsonResponse({
                "id": user.id,
                "username": username,
                "mobile": mobile,
                "token": token,
                "avatar": user.avatar})
# Post /authorizations/
"""用户登录视图"""
class LoginView(View):
    def post(self,request):
        dict = json.loads(request.body.decode())
        username = dict['username']
        password = dict['password']



        # 2.校验(整体 + 单个)
        if not all([username, password]):
            return JsonResponse({'code': 400,
                                 'errmsg': '缺少必传参数'})

        try:
            if re.match('^1[3-9]\d{9}$', username):
                # account 是手机号
                # 根据手机号从数据库获取 user 对象返回.
                user = User.objects.get(mobile=username)
            else:
                # account 是用户名
                # 根据用户名从数据库获取 user 对象返回.
                user = User.objects.get(username=username)
        except Exception as e:
            # 如果 account 既不是用户名也不是手机号
            # 我们返回 None
            return None

        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token
        user.save()


        return JsonResponse({
            "id": user.id,
            "username": user.username,
            "mobile": user.mobile,
            "token": user.token,
            "avatar": user.avatar})

"""修改上传头像到七牛云"""
# post /upload/avatar/
# class UploadAvatarView(View):
#     def post(self,request):
#         user = request.user
#
#         image_file = request.FILES.get('avatar', None)
#
#         # 2:校验参数
#         if image_file is None:
#             return JsonResponse({
#                 "code": 400,
#                 "errmsg": "图片没有输入，不能上传"
#             }, status=400)
#
#         # 3:数据处理---读取数据(二进制)，上传到七牛云，将返回的地址，保存到数据库
#         image_data = image_file.read()
#
#         try:
#             file_name = storage(image_data)
#
#         except Exception as e:
#             return JsonResponse({
#                 "code": 400,
#                 "errmsg": "图片上传失败"
#             })
#         try:
#             User.objects.filter(id=user.id).update(avatar=file_name)
#
#         except Exception as e:
#             return JsonResponse({
#                 "code": 400,
#                 "errmsg": "图片保存失败"
#             })
#         avatar_url = qiniuyun + str(file_name)
#         # 4:构建响应
#
#         return JsonResponse({
#
#             "imgurl": avatar_url
#         })

"""修改上传头像到FASTdfs"""
# post /upload/avatar/
class UploadAvatarView(View):
    def post(self,request):
        user = request.user
        image_file = request.FILES.get('avatar', None)

        # 2:校验参数
        if image_file is None:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片没有输入，不能上传"
            }, status=400)


        data = image_file.read()

        file_id = FDFSStorage()._save(name="",content=data)

        try:
            User.objects.filter(id=user.id).update(avatar=file_id)

        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片保存失败"
            })


        url= FDFSStorage().url(name=file_id)



        return JsonResponse({"imgurl": url})



# post  /upload/common/
"""前端的富文本编辑器需要上传图片"""
class UploadFrontView(View):
    def post(self,request):
        user = request.user

        image_file = request.FILES.get('upload', None)

        # 2:校验参数
        if image_file is None:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片没有输入，不能上传"
            }, status=400)

        # 3:数据处理---读取数据(二进制)，上传到七牛云，将返回的地址，保存到数据库
        image_data = image_file.read()

        try:
            file_name = storage(image_data)

        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片上传失败"
            })
        try:
            User.objects.filter(pk=user.id).update(avatar=file_name)

        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片保存失败"
            })
        avatar_url = qiniuyun + str(file_name)

        # 第二种用法: 将 reverse 和 redirect 搭配使用
        url ="/upload_success.html?image_url="+avatar_url+'&CKEditorFuncNum=1/'

        return redirect(url)


# http://127.0.0.1:8080/upload_success.html?image_url=http://qi9uu1ily.hn-bkt.clouddn.com/Fhd-Em_fGuRddF5Tm3TGOSi-17he&CKEditFuncNum=1&Message=302

# get  /user/
"""用户个人中心"""

class UserInfoView(View):

    def get(self,request):

        user = request.user

